﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
// The extension methods need to be brought into scope
using TheClerk.Forms.Templates.raw.Envelope;

using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.X509;

namespace TheClerk.Forms.Templates.raw.Envelope
{
    //#region ASN.1 stuff
    //public abstract class OID : Org.BouncyCastle.Asn1.DerObjectIdentifier
    //{
    //    public int[] asIntArray
    //    {
    //        get { return _oid_array.Clone() as int[]; }
    //        set { SetFromArray(value); }
    //    }

    //    public string asString
    //    {
    //        get { return this._oid_string.Clone() as string; }
    //        set { SetFromString(value); }
    //    }

    //    private string _oid_string;
    //    private int[] _oid_array;

    //    public override string ToString()
    //    {
    //        return asString;
    //    }

    //    public OID(string s = null, int[] i = null) : base(s) { }

    //    public OID(string oid) : base(oid)
    //    {
    //        SetFromString(oid);
    //    }

    //    public OID(int[] oid) : base(oid)
    //    {
    //        SetFromArray(oid);
    //    }

    //    private Object syncRoot = new Object();

    //    private void SetFromArray(int[] value)
    //    {
    //        if (value == null)
    //            throw new ArgumentNullException("value");
    //        if (value[0] < 0 || value[0] > 2)
    //            throw new FormatException("OID must start with 0, 1, or 2.");

    //        StringBuilder builder = new StringBuilder();
    //        foreach (int i in _oid_array)
    //            builder.Append(i + ".");
    //        builder.Remove(builder.Length - 1, 1);
    //        lock (syncRoot)
    //        {
    //            _oid_string = builder.ToString();
    //            _oid_array = value.Clone() as int[];
    //        }
    //    }

    //    private void SetFromString(string value)
    //    {
    //        // TODO: What if we send it the BouncyCastle name?
    //        string[] tokens = value.Split(new char[] { '.' });
    //        int[] intArray = new int[tokens.Length];
    //        for (int i = 0; i < tokens.Length; i++)
    //            intArray[i] = Convert.ToInt32(tokens[i]);
    //        // if it got here it's an OID-style string
    //        if (intArray[0] < 0 || intArray[0] > 2)
    //            throw new FormatException("First component of OID must be 0, 1, or 2");
    //        lock (syncRoot)
    //        {
    //            this._oid_array = intArray;
    //            this._oid_string = value;
    //        }
    //    }
    //}

    ///// <summary>
    ///// Imported from RFC5280 (i.ecdsaSigner., needs to be subclassed)
    ///// </summary>
    //public abstract class AlgorithmIdentifier : OID
    //{
    //    public AlgorithmIdentifier() : base() { }
    //    public AlgorithmIdentifier(string oid) : base(oid) { }
    //    public AlgorithmIdentifier(int[] oid) : base(oid) { }
    //}

    ///// <summary>
    ///// A hash algorithm's OID and such
    ///// </summary>
    //public class HashAlgorithmID : AlgorithmIdentifier
    //{
    //    private static Dictionary<string, string> algorithms = new Dictionary<string, string>();
    //    public HashAlgorithmID(string oid) : base(oid) { }
    //    public HashAlgorithmID(int[] oid) : base(oid) { }
    //    public static HashAlgorithmID GetAlgorithm(string algName){
    //        return new HashAlgorithmID(algorithms[algName]);
    //        //TODO: NotImplemented
    //        throw new NotImplementedException();
    //    }
    //}

    ///// <summary>
    ///// A symmetric algorithm's OID and such
    ///// </summary>
    //public class SymmetricAlgorithmID : AlgorithmIdentifier
    //{
    //}

    ///// <summary>
    ///// An asymmetric algorithm's OID and such
    ///// </summary>
    //public class AsymmetricAlgorithmID : AlgorithmIdentifier
    //{
    //    public AsymmetricAlgorithmID(string oid) : base(oid) { }
    //    public AsymmetricAlgorithmID(int[] oid) : base(oid) { }
    //}

    //public class ExtensionOID : OID {
    //    public ExtensionOID(string oid) : base(oid) { }
    //    public ExtensionOID(int[] oid) : base(oid) { }
    //}

    //#endregion

    /// <summary>
    /// For stamps
    /// </summary>
    /// <remarks>
    /// </remarks>
    public class TimeStamp
    {
        public TimeStamp() { }
        public Org.BouncyCastle.Tsp.TimeStampToken Token { get; internal set; }
        public TimeStamp(Org.BouncyCastle.Tsp.TimeStampToken alreadyDone) { Token = alreadyDone; }
    }

    /// <summary>
    /// Container for everything
    /// </summary>
    class X509Certificate
    {
        X509CertificateStructure Structure;
    }

    /// <summary>
    /// to-be-signed structure
    /// </summary>
    /// <remarks>
    /// This contains the standard TBSCertificate structure, and
    /// has the extensions added appropriately.
    /// </remarks>
    class X509CertificateStructure 
    {
        public Org.BouncyCastle.Asn1.X509.V3TbsCertificateGenerator tbsGenerator;
        public Org.BouncyCastle.Asn1.X509.X509ExtensionsGenerator extGenerator;
        public void SetPublicKey(AsymmetricIdentity pub)
        {
            tbsGenerator.SetSubjectPublicKeyInfo(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub.publicKey));
        }
    }



}
